package pear.algorithm;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import lombok.NoArgsConstructor;
import pear.other.MyBitSet;

/**
 *
 * @author Dingo
 */
@NoArgsConstructor
public class Algorithm {

    private static int WIDTH = 10240;
    
    /**
     * Metoda czyta bity z pliku PNG.
     * @param file plik PNG
     * @param bits zestaw bitów, do którego mają być dopisane bity.
     * @return zwraca liczbę przeczytanych bitów.
     */
    public int readBitsFromImage(File file, MyBitSet bits) {
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file);
        } catch (IOException ex) {
            Logger.getLogger(Algorithm.class.getName()).log(Level.SEVERE, null, ex);
        }
        int width = bi.getWidth();
        int height = bi.getHeight();
        int bitsCount = 0;
        //get file len
        MyBitSet lenInBit = new MyBitSet();
        for (int i = 0; i < 32; i++) {
            if (bi.getRGB(i, 0) == -1) {
                lenInBit.set(i);
            }
        }
        ByteBuffer bbLen = ByteBuffer.wrap(lenInBit.toByteArray(4));
        int len = bbLen.getInt(0);//in bits not bytes
        int lenInBits = len * 8;
        System.out.println(len);
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                if (!(i == 0 && j < 32)) {
                    if (bi.getRGB(j, i) == -1) {
                        bits.set(bitsCount);
                    }
                    bitsCount++;
                }
                if (bitsCount >= lenInBits) {
                    break;
                }

            }
        }
        return len;
    }
    
    public void writeBitsToImage(File file, BitSet bits) {
        int height = 1;
        for (int i = WIDTH; i < bits.length(); i += WIDTH) {
            height++;
        }
        int width = WIDTH;
        if (bits.length() < WIDTH) {
            width = bits.length();
        }
        BufferedImage bi = new BufferedImage(width, height,
                BufferedImage.TYPE_BYTE_BINARY);
        int idx = bits.nextSetBit(0);
        for (int i = 0; i < height; i++) {
            while (true) {
                //System.out.println("x:"+idx%width+" y:"+i);
                bi.setRGB(idx % width, i, -1);
                idx = bits.nextSetBit(idx + 1);
                //powinno być idx >= 0, ale mogła to być kaszana przy dzieleniu :P
                if (idx < 0 || (idx / ((i + 1) * width)) >= 1) {
                    break;
                }
            }
        }
        try {
            ImageIO.write(bi, "png", file);
        } catch (IOException ex) {
            Logger.getLogger(Algorithm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
